package com.lifeverse.repository;

import com.lifeverse.entity.ServiceDiscovery;
import com.lifeverse.entity.enums.HealthStatus;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 服务发现数据访问层
 */
@Repository
public interface ServiceDiscoveryRepository extends JpaRepository<ServiceDiscovery, Long> {

    /**
     * 根据服务名称查询所有实例
     */
    List<ServiceDiscovery> findByServiceName(String serviceName);

    /**
     * 根据实例ID查询
     */
    Optional<ServiceDiscovery> findByInstanceId(String instanceId);

    /**
     * 查询可用的服务实例
     */
    @Query("SELECT s FROM ServiceDiscovery s WHERE s.enabled = true AND s.status IN ('HEALTHY', 'WARNING') AND s.lastHeartbeat > :threshold")
    List<ServiceDiscovery> findAvailableServices(@Param("threshold") LocalDateTime threshold);

    /**
     * 根据服务名称查询可用实例
     */
    @Query("SELECT s FROM ServiceDiscovery s WHERE s.serviceName = :serviceName AND s.enabled = true AND s.status IN ('HEALTHY', 'WARNING') AND s.lastHeartbeat > :threshold ORDER BY s.weight DESC")
    List<ServiceDiscovery> findAvailableServicesByName(@Param("serviceName") String serviceName, @Param("threshold") LocalDateTime threshold);

    /**
     * 查询心跳过期的服务
     */
    @Query("SELECT s FROM ServiceDiscovery s WHERE s.enabled = true AND s.lastHeartbeat < :threshold")
    List<ServiceDiscovery> findExpiredHeartbeatServices(@Param("threshold") LocalDateTime threshold);

    /**
     * 根据环境查询服务
     */
    List<ServiceDiscovery> findByEnvironment(String environment);

    /**
     * 根据区域查询服务
     */
    List<ServiceDiscovery> findByRegion(String region);

    /**
     * 根据标签查询服务
     */
    @Query("SELECT s FROM ServiceDiscovery s JOIN s.tags t WHERE t = :tag")
    List<ServiceDiscovery> findByTag(@Param("tag") String tag);

    /**
     * 根据多个标签查询服务
     */
    @Query("SELECT s FROM ServiceDiscovery s WHERE s.tags IN :tags")
    List<ServiceDiscovery> findByTags(@Param("tags") List<String> tags);

    /**
     * 统计各服务的实例数量
     */
    @Query("SELECT s.serviceName, COUNT(s) FROM ServiceDiscovery s WHERE s.enabled = true GROUP BY s.serviceName")
    List<Object[]> countInstancesByService();

    /**
     * 统计各状态的服务数量
     */
    @Query("SELECT s.status, COUNT(s) FROM ServiceDiscovery s WHERE s.enabled = true GROUP BY s.status")
    List<Object[]> countByStatus();

    /**
     * 统计各环境的服务数量
     */
    @Query("SELECT s.environment, COUNT(s) FROM ServiceDiscovery s WHERE s.enabled = true GROUP BY s.environment")
    List<Object[]> countByEnvironment();

    /**
     * 查询负载最低的服务实例
     */
    @Query("SELECT s FROM ServiceDiscovery s WHERE s.serviceName = :serviceName AND s.enabled = true AND s.status IN ('HEALTHY', 'WARNING') AND s.lastHeartbeat > :threshold ORDER BY s.weight DESC")
    List<ServiceDiscovery> findLeastLoadedInstances(@Param("serviceName") String serviceName, @Param("threshold") LocalDateTime threshold);

    /**
     * 查询特定版本的服务
     */
    List<ServiceDiscovery> findByServiceNameAndVersion(String serviceName, String version);

    /**
     * 查询服务的所有版本
     */
    @Query("SELECT DISTINCT s.version FROM ServiceDiscovery s WHERE s.serviceName = :serviceName AND s.enabled = true ORDER BY s.version")
    List<String> findVersionsByServiceName(@Param("serviceName") String serviceName);

    /**
     * 删除过期的服务注册记录
     */
    @Query("DELETE FROM ServiceDiscovery s WHERE s.enabled = false AND s.lastHeartbeat < :threshold")
    void deleteExpiredServices(@Param("threshold") LocalDateTime threshold);

    /**
     * 获取服务注册趋势
     */
    @Query("SELECT DATE(s.registeredAt) as date, COUNT(s) as count " +
           "FROM ServiceDiscovery s " +
           "WHERE s.registeredAt >= :since " +
           "GROUP BY DATE(s.registeredAt) " +
           "ORDER BY date DESC")
    List<Object[]> getRegistrationTrend(@Param("since") LocalDateTime since);

    /**
     * 查询同一主机上的所有服务
     */
    List<ServiceDiscovery> findByHost(String host);

    /**
     * 查询使用特定端口的服务
     */
    List<ServiceDiscovery> findByPort(Integer port);

    /**
     * 查询主机和端口组合
     */
    Optional<ServiceDiscovery> findByHostAndPort(String host, Integer port);

    /**
     * 获取服务健康状态分布
     */
    @Query("SELECT s.serviceName, s.status, COUNT(s) as count " +
           "FROM ServiceDiscovery s " +
           "WHERE s.enabled = true " +
           "GROUP BY s.serviceName, s.status " +
           "ORDER BY s.serviceName, s.status")
    List<Object[]> getServiceHealthDistribution();
}